Skip to content

fix(git): pick the credential for the transport the remote actually uses - #270

Merged
viniciussanchez merged 2 commits into
HashLoad:mainfrom
isaquepinheiro:fix/auth-transport-mismatch
Aug 3, 2026
Merged

fix(git): pick the credential for the transport the remote actually uses#270
viniciussanchez merged 2 commits into
HashLoad:mainfrom
isaquepinheiro:fix/auth-transport-mismatch

Conversation

@isaquepinheiro

Copy link
Copy Markdown
Contributor

Depende do #269. Esta branch está empilhada nele para o CI passar, então o diff mostra dois commits. Mergeando o #269 primeiro, este PR reduz sozinho ao commit fix(git):.

Validado antes de subir: PR de validação no fork com os 6 checks verdes, lint incluído.

O problema

Com qualquer auth SSH cadastrada para um host (boss login <host> -s), todo fetch de dependência daquele host falha — e o Boss reporta sucesso mesmo assim:

🔁 github_com_hashload_jsonbr    Updating...
⚠️ Fail to fetch repository github.com/hashload/jsonbr: invalid auth method
📦 github_com_hashload_jsonbr    Installed
✅ Installation completed successfully!

Exit 0. O projeto fica congelado na versão que já estava em cache, em silêncio. Em CI isso passa verde.

Causa

A credencial é buscada pelo prefixo do host, mas o transporte vem da URL que o repositório realmente busca. Os dois discordam sempre que um cache foi clonado por HTTPS antes de uma auth SSH existir para aquele host: dep.GetURL() passa a devolver a forma SSH assim que auth.UseSSH está setado, enquanto o remote em cache continua HTTPS.

O go-git v5.4.2 ignorava uma credencial SSH entregue ao transporte HTTP e buscava anonimamente. Desde o bump para v5.19.1 ele devolve transport.ErrInvalidAuthMethod. A construção de URL do Boss é idêntica entre v3.0.12 (models/dep.go:47-56) e hoje (internal/core/domain/dependency.go:65-84) — o que mudou foi a dependência.

A correção

Configuration.GetAuthForURL(repo, rawURL) resolve a credencial contra a URL efetiva e devolve nil quando ela não serve ao transporte, restaurando o fetch anônimo que o go-git fazia sozinho. Repositório privado alcançado pelo transporte errado continua falhando, exatamente como antes.

Os cinco call sites passaram a informar a URL real:

  • clone → dep.GetURL()
  • fetch/pull/submódulos → o remote do repositório em cache, via o helper remoteURL()

O erro de fetch em UpdateCacheEmbedded estava em msg.Debug — invisível em verbosidade normal. Virou msg.Warn dizendo que a cópia em cache está sendo usada.

Medição

Mesmo cache, mesma auth SSH, mesmo projeto (HashLoad/ormbr), sem boss-lock.json, com o cache faltando a tag mais nova do hashload/cqlbr. Só troca o binário:

sem o fix com o fix
invalid auth method nenhum
tags no cache depois 8 — não buscou 9 — buscou e restaurou
cqlbr resolvido 1.1.6 1.1.51
exit code 0 0

O 1.1.6 é o dano concreto. Paridade com o v3.0.12 conferida no mesmo snapshot de cache — os quatro módulos resolvem idêntico:

cqlbr = 1.1.51   dbcbr = 1.1.7   dbebr = 1.1.7   jsonbr = 1.1.6

Testes

go test ./... verde nos 29 pacotes. Seis testes novos em pkg/env/auth_transport_test.go:

  • credencial SSH em remote HTTPS → descartada
  • credencial usuário/senha em remote SSH → descartada
  • credencial que casa com o transporte → preservada
  • host sem credencial → nil
  • URL desconhecida → mantém o comportamento anterior, não descarta silenciosamente
  • detecção de transporte: git@host:path, ssh://, https://, http:// e https://user@host/path, que não pode ser confundido com sintaxe scp

A chave ed25519 é gerada e cifrada em tempo de execução, então o teste não depende de chave no ambiente.

Independência

Verificado com git merge-tree:

  • fix/auth-transport-mismatchmain : limpo
  • fix/legacy-auth-and-versionmain : limpo
  • as duas branches entre si : sem conflito

Os dois fixes também foram mesclados localmente para o teste E2E, sem conflito. Podem ser mergeados em qualquer ordem.

Fora de escopo

Falha de fetch continua não alterando o exit code. Endurecer isso muda a política para quem trabalha offline ou atrás de rede instável, e não é o que este bug exige — com o fix, o invalid auth method deixa de acontecer. Se quisermos endurecer mesmo, vale discutir separado, porque afeta CI de terceiros.

🤖 Generated with Claude Code

isaquepinheiro and others added 2 commits August 3, 2026 11:11
The Lint job was already red when HashLoad#268 merged, on two findings from that PR:

  setup/migrations.go:59: cognitive complexity 25 of func `seven` (gocognit)
  pkg/env/legacy_auth_test.go:76: declaration of "err" shadows line 70 (govet)

`seven` grew past the threshold because the rewrite dropped the //nolint the
original carried. Rather than put the suppression back, the per-entry work
moves into migrateLegacyAuth and the decrypt-or-warn step into decryptLegacy,
which reads better than the three near-identical blocks it replaces and takes
the complexity down on its own.

No behaviour change: `go test ./...` stays green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The credential is looked up by host prefix, but the transport comes from the
URL the repository fetches from. Those disagree whenever a cache was cloned
over HTTPS before an SSH login was configured for that host: dep.GetURL()
returns the SSH form once auth.UseSSH is set, while the cached remote stays
HTTPS.

go-git v5.4.2 ignored an SSH credential handed to the HTTP transport and
fetched anonymously. Since the upgrade to v5.19.1 it returns
transport.ErrInvalidAuthMethod instead, so every fetch for that host fails --
and because a failed fetch only warned, Boss still reported
"Installation completed successfully" and exited 0. The project silently
stayed on whatever the cache last held.

Measured against v3.0.12 on the same cache, same auth and same project, with
a cache missing the newest tag of hashload/cqlbr:

  without this change: 4x "invalid auth method", cache untouched, cqlbr 1.1.6
  with this change:    no warning, tag restored, cqlbr 1.1.51 (v3.0.12 parity)

GetAuthForURL resolves the credential against the effective remote URL and
returns nil when it does not fit the transport, which restores the anonymous
fetch go-git used to perform on its own. A private repository reached over
the wrong transport still fails, exactly as it did before.

The fetch failure in UpdateCacheEmbedded was logged at debug level, so it was
invisible at normal verbosity. It now warns and says the cached copy is being
used, which is the difference between "up to date" and "whatever was cached".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 30.18868% with 37 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@e14d2a7). Learn more about missing BASE report.

Files with missing lines Patch % Lines
setup/migrations.go 0.00% 25 Missing ⚠️
internal/adapters/secondary/git/git.go 0.00% 8 Missing ⚠️
internal/adapters/secondary/git/git_embedded.go 0.00% 4 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #270   +/-   ##
=======================================
  Coverage        ?   28.54%           
=======================================
  Files           ?       90           
  Lines           ?     5700           
  Branches        ?        0           
=======================================
  Hits            ?     1627           
  Misses          ?     3933           
  Partials        ?      140           
Flag Coverage Δ
unittests 28.54% <30.18%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@viniciussanchez
viniciussanchez merged commit 6a60357 into HashLoad:main Aug 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants